package com.forestar.mapControl.mappool;

import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Color;
import android.graphics.drawable.BitmapDrawable;
import android.os.Environment;
import android.text.TextUtils;

import com.forestar.mapControl.utils.BitmapUtils;
import com.forestar.mapControl.utils.LogD;
import com.forestar.mapControl.utils.bitmapcache.BitmapLruCache;
import com.forestar.mapControl.utils.bitmapcache.CacheableBitmapDrawable;
import com.forestar.mapControl.utils.mapConvert.convert.ConvertHelper2;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;

import static com.forestar.mapControl.mappool.MzTileBean.LOAD_STATE_COMPLETE;
import static com.forestar.mapControl.mappool.MzTileBean.LOAD_STATE_FAIL;
import static com.forestar.mapControl.mappool.MzTileBean.LOAD_STATE_NO;

/**
 * created by  xzk
 * 2020/7/27   14:52
 * 说明:  地图缓存池  这个是使用 下载分任务，刷新在单独线程的策略
 */
public class MapCachePool2 {

    //  //工作线程及任务  kEY：要加载的瓦片   value：当前任务的加载状态
//    private final Map<Long, Integer> mWorking = new HashMap<>();
    // kEY：要加载的瓦片地址   value：任务详细信息   当任务完成时（瓦片加载完毕，就从这里删除）
    private final ConcurrentHashMap<String, MzTileBean> mWorking = new ConcurrentHashMap<>();
    //todo 用三级缓存试一下，尽量自己不写回收监听
//    //todo 享元模式，保存复用的bitmap，获取效率更快，，，什么条件下需要删除呢？三级缓存清除的时候
//    private final HashMap<String, CacheableBitmapDrawable> cacheMapPool = new HashMap<>();

    //删除屏幕外的任务列表(还能去重)
    private HashSet<String> noScreenTile = new HashSet<>();
    private HashSet<String> allScreenTileHasLoad = new HashSet<>();

    private Context mContext;
    private BitmapLruCache bitmapCache;
    private final Bitmap zhanweiBitmap;
    private CacheableBitmapDrawable aNullBitmap;

    public void setmContextAndInitCache(Context mContext) {
        this.mContext = mContext;
        if (null != mContext) {
            synchronized (MapCachePool2.class) {
                String tilePath = Environment.getExternalStorageDirectory().getAbsolutePath() + File.separator + "testGis" + File.separator;
                bitmapCache = (new BitmapLruCache.Builder(mContext)).setMemoryCacheEnabled(true)
                        .setMemoryCacheMaxSize(BitmapUtils.calculateMemoryCacheSize(mContext))
                        .setDiskCacheEnabled(true)
                        .setDiskCacheMaxSize(200)
                        .setDiskCacheLocation(new File(tilePath)).build();
                aNullBitmap = bitmapCache.putInMemoryCache("null", zhanweiBitmap);
            }
        }
    }

    private static MapCachePool2 mapCachePool;

    private MapCachePool2() {
        zhanweiBitmap = createSolidColorBitmap();

    }

    public static MapCachePool2 getInstance() {
        if (null == mapCachePool) {
            synchronized (MapCachePool2.class) {
                if (null == mapCachePool) {
                    mapCachePool = new MapCachePool2();
                }
            }
        }
        return mapCachePool;
    }

    /**
     * 获取全部任务
     *
     * @return
     */
    public Map<String, MzTileBean> getmWorking() {
        return mWorking;
    }


    /**
     * 获取第一个任务
     *
     * @return
     */
    public MzTileBean getFirstWorkTask() {
        //随机的位置？
//        synchronized (mWorking) {
            Set<String> set = mWorking.keySet();
            String keys = null;
            for (String key : set) {
                keys = key;
                MzTileBean tileBean = mWorking.get(keys);
                if (null != tileBean && tileBean.getState() == LOAD_STATE_NO) {
                        return tileBean;
                }
            }
            return null;
//        }
    }

//是否是屏幕需要的
    public boolean isInScreen(String key){
        if(noScreenTile!= null){
           return noScreenTile.contains(key);
        }
        return false;
    }
    //判断是否已经绘制过
    public boolean isDrawInScreen(String key){
        if(allScreenTileHasLoad!= null){
            return allScreenTileHasLoad.contains(key);
        }
        return false;
    }

    //删除全部任务
    public void removeAllTask( ) {
//        synchronized (mWorking) {
            mWorking.clear();
//        }
    }
    //删除任务
    public void removeTask(MzTileBean tileBean) {
//        synchronized (mWorking) {
            if (null != tileBean) {
                mWorking.remove(tileBean.getCacheKey());
            }
//        }
    }

    public  HashSet<String> getNoScreenTile(){
        return noScreenTile;
    }
    //所有屏幕上已经加载过的图片
    public  HashSet<String> getAllScreenTileHasLoad(){
        return allScreenTileHasLoad;
    }


    public void showAllCache(String keys){
        LogD.d("是否存在？"+bitmapCache.containsInMemoryCache(keys));
    }
    /**
     * 有给个默认值
     *
     * @param mzTileBean
     * @return
     */
    public CacheableBitmapDrawable getBitmapForShow(MzTileBean mzTileBean) {
        if (null != mzTileBean && !TextUtils.isEmpty(mzTileBean.getCacheKey())) {
            CacheableBitmapDrawable bitmapDrawable = getBitmapFromMemory(mzTileBean.getCacheKey());
            //位图可用，则展示出最新的图片，否则加入到任务池中，并返回占位图
            if (null != bitmapDrawable && bitmapDrawable.isBitmapValid()) {
                if(null != mzTileBean.getTileRect()){
//                    bitmapDrawable.setBounds(mzTileBean.getTileRect());
                }
                return bitmapDrawable;
            }
//            MzTileBean tileBean = mWorking.get(mzTileBean.getCacheKey());
//            if (null != tileBean && tileBean.getState() == LOAD_STATE_COMPLETE) {
//                tileBean.setTileRect(mzTileBean.getTileRect());
//            } else {
//                if(null== tileBean ||tileBean.getState() == LOAD_STATE_NO){
//                    synchronized (mWorking) {
//                        mWorking.put(mzTileBean.getCacheKey(), mzTileBean);
//                    }
//                }
//            }
        }
        return null;
    }

    /**
     * 不做显示的，就不扰乱加载顺序，直接放入内存吧
     *
     * @param mzTileBean
     * @return
     */
    public void putForRequestTaskIfNeed(MzTileBean mzTileBean) {
        if (null != mzTileBean && !TextUtils.isEmpty(mzTileBean.getCacheKey())) {
//            synchronized (mWorking) {
                mzTileBean.setState(LOAD_STATE_NO);
                mWorking.put(mzTileBean.getCacheKey(), mzTileBean);
//            }
        }
    }

//如果任务过多，就删除暂时不需要的任务，，，解决冗余任务的问题
    private void removeLastTask(){
        if(mWorking.size()>100 && noScreenTile!= null){
//            synchronized (mWorking) {
                Iterator<Map.Entry<String, MzTileBean>> iteratorWorking2 = mWorking.entrySet().iterator();
                Map.Entry<String, MzTileBean> nextKey2 = iteratorWorking2.next();
                String key2 = nextKey2.getKey();
                if(noScreenTile.contains(key2)){
                }else {
                    mWorking.remove(key2);
                }
//            }
        }
    }

    //创建一张纯色bitmap
    public Bitmap createSolidColorBitmap() {
        Bitmap bitmap = Bitmap.createBitmap(266, 266,
                Bitmap.Config.ARGB_8888);
        //此颜色带透明度
        bitmap.eraseColor(Color.parseColor("#ffffff"));//填充颜色
        return bitmap;
    }
    public Bitmap createSolidRedColorBitmap() {
        Bitmap bitmap = Bitmap.createBitmap(266, 266,
                Bitmap.Config.ARGB_8888);
        //此颜色带透明度
        bitmap.eraseColor(Color.RED);//填充颜色
        return bitmap;
    }
    public Bitmap createSolidGreenColorBitmap() {
        Bitmap bitmap = Bitmap.createBitmap(266, 266,
                Bitmap.Config.ARGB_8888);
        //此颜色带透明度
        bitmap.eraseColor(Color.GREEN);//填充颜色
        return bitmap;
    }

    /**
     * 保存drawable  当加载完成后，保存到内存池中
     *
     * @return
     */
    public CacheableBitmapDrawable putBitmapFromTask(MzTileBean cacheTile, Bitmap bitmapDrawable) {
        if (null != cacheTile && null != bitmapDrawable) {
            String cacheKey = cacheTile.getCacheKey();
            //todo 用上三级缓存，但只是为了避免oom，不做直接引用
            CacheableBitmapDrawable cacheableBitmapDrawable = buildCacheableBitmapDrawable(cacheKey, bitmapDrawable);
            if(null != cacheableBitmapDrawable){
                if(null != cacheTile.getTileRect()){
//                    cacheableBitmapDrawable.setBounds(cacheTile.getTileRect());
                }
                return cacheableBitmapDrawable;
            }
        }
        return null;
    }

    /**
     * 构建bitmap并进行缓存保存
     *
     * @param cacheKey
     * @param bitmapDrawable
     * @return
     */
    private CacheableBitmapDrawable buildCacheableBitmapDrawable(String cacheKey, Bitmap bitmapDrawable) {
        if (null != bitmapCache) {
            return bitmapCache.put(cacheKey, bitmapDrawable);
        }
        return null;
    }

    /**
     * 从缓存获取图片
     *
     * @param cacheKey
     * @return CacheableBitmapDrawable
     */
    public CacheableBitmapDrawable getBitmapFromMemory(String cacheKey) {
        if (null != bitmapCache) {
            CacheableBitmapDrawable memoryCache = bitmapCache.getFromMemoryCache(cacheKey);
            return memoryCache;
        }
        return null;
    }

    /**
     * 获取drawable
     *
     * @return
     */
    public CacheableBitmapDrawable getBitmapDrawable(MzTileBean cacheTile) {
        if (null == cacheTile || TextUtils.isEmpty(cacheTile.getCacheKey())) {
            return null;
        }
        String cacheKey = cacheTile.getCacheKey();
        CacheableBitmapDrawable bitmapDrawable = getBitmapFromMemory(cacheKey);
        if (null != bitmapDrawable && bitmapDrawable.isBitmapValid()) {
            return bitmapDrawable;
        }
        return bitmapDrawable;
    }

}
